#pragma once
#ifndef VECTOR3_H_
#define VECTOR3_H_

#include <math.h>

namespace EPOC
{
	class Vector3
	{
	public:
		Vector3() : m_fX(0.0f), m_fY(0.0f), m_fZ(0.0f){};
		Vector3(float fX, float fY, float fZ) : m_fX(fX), m_fY(fY), m_fZ(fZ){};

		virtual float Length()				{ return sqrtf( ( m_fX * m_fX ) + ( m_fY * m_fY ) + ( m_fZ * m_fZ )); }
		virtual float LengthSq()			{ return ( m_fX * m_fX ) + ( m_fY * m_fY )+ ( m_fZ * m_fZ ); }
		virtual void Normalize()			{ float fLength = Length(); m_fX /= fLength; m_fY /= fLength;; m_fZ /= fLength;}
		virtual Vector3 NormalizeCopy()		{ Vector3 vNormalized; float fLength = Length(); vNormalized.m_fX = m_fX / fLength; vNormalized.m_fY = m_fY / fLength; vNormalized.m_fZ = m_fZ / fLength;return vNormalized; }

		virtual float DotProduct(Vector3 *pVector)	{ return m_fX * pVector->m_fX + m_fY * pVector->m_fY + m_fZ * pVector->m_fZ; }
		//virtual Vector3 Perpendicular()				{ Vector3 vPerpendicular; vPerpendicular.m_fX = -m_fY; vPerpendicular.m_fY = m_fX; return vPerpendicular; }
		
		const Vector3 Vector3::operator+(const Vector3 &other) const 
		{
			Vector3 result = *this;  

			result.m_fX += other.m_fX;
			result.m_fY += other.m_fY;
			result.m_fZ += other.m_fZ;
		
			return result;            
		}

		const Vector3 Vector3::operator-(const Vector3 &other) const 
		{
			Vector3 result = *this;  
			
			result.m_fX -= other.m_fX;
			result.m_fY -= other.m_fY;
			result.m_fZ -= other.m_fZ;
		
		
			return result;           
		}

		const Vector3 Vector3::operator*(const float &other) const 
		{
			Vector3 result = *this; 
			result.m_fX *= other;
			result.m_fY *= other;
			result.m_fZ *= other;
		
			return result;           
		}

		const Vector3 Vector3::operator/(const float &other) const 
		{
			Vector3 result = *this; 
			result.m_fX /= other;
			result.m_fY /= other;
			result.m_fZ /= other;
		
			return result;           
		}

		Vector3& Vector3::operator+=(const Vector3& right)
		{
			*this = *this + right;
			return *this;
		}

		Vector3& Vector3::operator-=(const Vector3& right)
		{
			*this = *this - right;
			return *this;
		}

		Vector3& Vector3::operator*=(const float& right)
		{
			*this = *this * right;
			return *this;
		}

		Vector3& Vector3::operator/=(const float& right)
		{
			*this = *this / right;
			return *this;
		}

		bool Vector3::operator==(const Vector3 &other) const 
		{
			return (this->m_fX == other.m_fX && this->m_fY == other.m_fY && this->m_fZ == other.m_fZ);
		}

		bool Vector3::operator!=(const Vector3 &other) const 
		{
			return !(*this == other);
		}

	public:
		float m_fX;
		float m_fY;
		float m_fZ;
	
	}; // class Vector3
}; // namespace EPOC

#endif